package org.jsola.hr.provider;

import org.jsola.hr.query.permission.RoleMemberQuery;
import org.jsola.hr.vo.HrUserVO;
import org.jsola.hr.vo.permission.RoleMemberVO;
import org.jsola.permission.dto.*;
import org.jsola.permission.entity.*;
import org.jsola.permission.query.GroupQuery;
import org.jsola.permission.query.RoleQuery;
import org.jsola.permission.vo.*;
import org.jsola.user.core.TokenUser;

import java.util.List;
import java.util.Map;

/**
 * @author june
 */
public interface IPermissionProviderService {

    /**
     * 验证用户是否拥有某个对象的权限
     *
     * @param userId      用户id
     * @param siteId      站点id
     * @param subjectId   业务ID
     * @param subjectType 业务类型
     * @return 拥有权限：true，否则false
     */
    boolean hasRight(String userId, String siteId, String subjectId, String subjectType);

    /**
     * 验证用户是否拥有指定权限
     *
     * @param userId           用户id
     * @param siteId           站点id
     * @param permissionString 权限字符串 如site:product.manager:save:1
     * @return 拥有权限：true，否则false
     */
    boolean hasRight(String userId, String siteId, String permissionString);

    /**
     * 验证用户是否拥有所有指定权限
     *
     * @param userId           用户id
     * @param siteId           站点id
     * @param permissionString 权限字符串 如site:product.manager:save:1
     * @return 拥有权限：true，否则false
     */
    boolean hasAllRight(String userId, String siteId, String... permissionString);

    /**
     * 验证用户是否拥有以下指定权限的某一个权限
     *
     * @param userId           用户id
     * @param siteId           站点id
     * @param permissionString 权限字符串 如site:product.manager:save:1
     * @return 拥有权限：true，否则false
     */
    boolean hasAnyRight(String userId, String siteId, String... permissionString);

    /**
     * 验证用户是否拥有某个实例指定权限
     *
     * @param userId           用户id
     * @param siteId           站点id
     * @param subjectId        业务ID
     * @param permissionString 权限字符串 如site:product.manager:save 不能添加实例
     * @return 拥有权限：true，否则false
     */
    boolean hasObjRight(String userId, String siteId, String subjectId, String permissionString);


    /**
     * 验证用户是否拥有某个实例所有指定权限
     *
     * @param userId           用户id
     * @param siteId           站点id
     * @param subjectId        业务ID
     * @param permissionString 权限字符串 如site:product.manager:save 不能添加实例
     * @return 拥有权限：true，否则false
     */
    boolean hasObjAllRight(String userId, String siteId, String subjectId, String... permissionString);

    /**
     * 验证用户是否拥有某个实例以下指定权限的某一个权限
     *
     * @param userId           用户id
     * @param siteId           站点id
     * @param subjectId        业务ID
     * @param permissionString 权限字符串 如site:product.manager:save 不能添加实例
     * @return 拥有权限：true，否则false
     */
    boolean hasObjAnyRight(String userId, String siteId, String subjectId, String... permissionString);

    /**
     * 验证用户是否是该对象的管理员
     *
     * @param userId      用户id
     * @param siteId      站点id
     * @param subjectId   业务ID
     * @param subjectType 业务类型
     * @return 是管理员：true，否则false
     */
    boolean isAdmin(String userId, String siteId, String subjectId, String subjectType);

    /**
     * 验证用户是否是该对象的管理员,会校验用户不属于某个组，不添加该组权限
     *
     * @param userId      用户id
     * @param siteId      站点id
     * @param subjectId   业务ID
     * @param subjectType 业务类型
     * @return 是管理员：true，否则false
     */
    boolean isAdminValidaGroup(String userId, String siteId, String subjectId, String subjectType);

    /**
     * 根据subjectType查询站点角色列表
     *
     * @param subjectType 业务类型
     * @param siteId      站点id
     * @return 角色列表
     */
    List<RoleDO> querySiteRoleList(String subjectType, String siteId);


    /**
     * 在指定角色中加入成员
     *
     * @param userId      用户id
     * @param roleId      角色id
     * @param subjectType 业务类型
     * @param subjectId   业务id
     * @param tokenUser   当前登录用户
     */
    void addRoleMember(String userId, Long roleId, String subjectType, String subjectId, TokenUser tokenUser);

    /**
     * 在指定角色中加入组成员
     *
     * @param groupId     组织id
     * @param roleId      角色id
     * @param subjectType 业务类型
     * @param subjectId   业务id
     * @param tokenUser   当前登录用户
     */
    void addGroupRoleMember(String groupId, Long roleId, String subjectType, String subjectId, TokenUser tokenUser);

    /**
     * 查询指定用户所属的角色ID集合（不包括所属组的角色）
     *
     * @param userId      用户ID
     * @param subjectType 业务类型，如果为null，则不过滤此参数
     * @param subjectId   业务对象ID，如果为null，则不过滤此参数
     * @param siteId      站点ID
     * @return 角色ID集合
     */
    List<Long> findRoleIdListByUserId(String userId, String subjectType, String subjectId, String siteId);

    /**
     * 删除指定角色下的指定成员（人员或组）
     *
     * @param userId      需要删除的用户id
     * @param roleId      要删除的用户角色
     * @param subjectType 业务类型
     * @param subjectId   业务id
     * @param siteId      站点id
     */
    void deleteRoleMember(String userId, Long roleId, String subjectType, String subjectId, String siteId);

    /**
     * 删除指定角色下的指定成员（人员或组）
     *
     * @param roleMemberId 角色成员
     * @param tokenUser    当前登录用户
     */
    void deleteRoleMemberById(Long roleMemberId, TokenUser tokenUser);

    /**
     * 查询角色
     *
     * @param roleId 角色id
     * @param siteId 站点id
     * @return 角色
     */
    RoleDO findRoleById(Long roleId, String siteId);

    /**
     * 查询角色
     *
     * @param roleIds 角色id
     * @param siteId  站点id
     * @return 角色
     */
    List<RoleDO> selectRoleByIds(List<Long> roleIds, String siteId);

    /**
     * 新增角色
     *
     * @param roleAddDTO 角色
     * @param tokenUser  当前登录用户
     * @return 角色对象
     */
    RoleVO addRole(RoleAddDTO roleAddDTO, TokenUser tokenUser);

    /**
     * 修改角色
     *
     * @param roleUpdateDTO 角色
     * @param tokenUser     当前登录用户
     */
    void updateRole(RoleUpdateDTO roleUpdateDTO, TokenUser tokenUser);

    /**
     * 删除角色
     *
     * @param roleId    角色id
     * @param tokenUser 当前登录用户
     */
    void deleteRoleById(Long roleId, TokenUser tokenUser);


    /**
     * 删除角色
     *
     * @param tokenUser 角色id
     * @param roleIds   当前登录用户
     */
    void deleteRoleByIds(TokenUser tokenUser, Long... roleIds);

    /**
     * 查询指定业务对象类型下的所有角色集合,返回组装成展示DTO
     *
     * @param roleQuery 查询对象
     * @param siteId    站点ID
     * @return 角色列表DTO集合
     */
    List<RoleListVO> queryRoleList(RoleQuery roleQuery, String siteId);

    /**
     * 查询用户角色列表
     *
     * @param userId      用户id
     * @param subjectType 业务类型
     * @param subjectId   业务id
     * @param siteId      站点id
     * @return 用户角色列表
     */
    List<RoleDO> findRoleListByUserId(String userId, String subjectType, String subjectId, String siteId);

    /**
     * 查询角色权限树，包含每个原子权限的授权状态
     *
     * @param subjectType 业务类型
     * @param siteId      站点id
     * @param roleId      角色id
     * @return 展示list
     */
    List<RoleRightListVO> queryRightList(String subjectType, String siteId, Long roleId);

    /**
     * 保存角色权限
     *
     * @param currUserId        当前用户id
     * @param roleId            角色id
     * @param subjectType       业务类型
     * @param subjectIdArray    业务id集合 默认角色的subjectId 是0
     * @param permissionIdArray 权限id集合
     * @param siteId            站点id
     */
    void saveRoleRight(String currUserId,
                       Long roleId,
                       String subjectType,
                       String[] subjectIdArray,
                       Long[] permissionIdArray,
                       String siteId);

    /**
     * 查询站点下的角色成员列表
     *
     * @param roleMemberQuery 查询对象
     * @param tokenUser       当前登录用户
     * @return 成员id列表
     */
    List<RoleMemberVO> queryRoleMemberList(RoleMemberQuery roleMemberQuery, TokenUser tokenUser);

    /**
     * 查询站点下第一个超级管理员
     *
     * @param type        成员类型
     * @param subjectType 主题类型
     * @param subjectId   主题id
     * @param siteId      站点id
     * @return 用户id
     */
    String findMemberIdBySubject(String type, String subjectType, String subjectId, String siteId);

    /**
     * 查询某个角色的所有用户
     * @param type
     * @param subjectType
     * @param subjectId
     * @param siteId
     * @return
     */
    List<String> findMemberListBySubject(String type, String subjectType, String subjectId, String siteId);

    List<RoleMemberVO> queryRoleMemberListFilterNameAndPhone(RoleMemberQuery roleMemberQuery, TokenUser tokenUser);

    /**
     * 批量新增角色成员
     *
     * @param roleMemberAddDTOList 新增角色成员DTO
     * @param tokenUser            当前用户
     */
    void addRoleMemberBatch(List<RoleMemberAddDTO> roleMemberAddDTOList, TokenUser tokenUser);

    /**
     * 获取业务类型下的角色下的原子权限数的map
     *
     * @param subjectType 对象类型
     * @param siteId      站点id
     * @return key：roleId   value：原子权限数
     */
    Map<String, Long> getRoleRightCountMap(String subjectType, String siteId);

    Map<String, Long> getRoleRightCountMap(List<String> subjectTypeList, String siteId);

    /**
     * 查询角色成员
     *
     * @param roleMemberQuery 查询条件
     * @param siteId          所属站点id
     * @return 角色成员列表信息
     */
    List<RoleMemberListVO> selectRoleMemberList(org.jsola.permission.query.RoleMemberQuery roleMemberQuery, String siteId);

    /**
     * 获取用户有权限的公司
     *
     * @param userId 用户id
     * @param siteId 站点
     * @return 用户有权限的公司
     */
    List<String> listCompanyUserHasRole(String userId, String siteId);

    /**
     * 删除用户所有角色成员
     *
     * @param tokenUser 当前登录用户
     * @param userId    用户id
     */
    void deleteUserRoleMember(TokenUser tokenUser, String... userId);

    /**
     * 将用户加为公司管理员
     *
     * @param companyId 公司id
     * @param tokenUser 当前用户
     * @param userIds   用户ids
     */
    void addUserToCompanyAdmin(String companyId, TokenUser tokenUser, String... userIds);

    /**
     * 将组加为公司管理员
     *
     * @param companyId 公司id
     * @param tokenUser 当前用户
     * @param groupIds  组ids
     */
    void addGroupToCompanyAdmin(String companyId, TokenUser tokenUser, String... groupIds);

    /**
     * 将用户从公司管理员移除
     *
     * @param companyId 公司id
     * @param tokenUser 当前用户
     * @param userIds   用户ids
     */
    void removeUserFormCompanyAdmin(String companyId, TokenUser tokenUser, String... userIds);

    /**
     * 将组从公司管理员移除
     *
     * @param companyId 公司id
     * @param tokenUser 当前用户
     * @param groupIds  组ids
     */
    void removeGroupFormCompanyAdmin(String companyId, TokenUser tokenUser, String... groupIds);

    /**
     * 获取对象类型下的所有原子权限
     *
     * @param subjectType 对象类型
     * @return list
     */
    List<PermissionDO> getPermissionList(String subjectType);

    /**
     * 根据权限编码，查询原子权限列表
     *
     * @param enNameList
     * @return
     */
    List<PermissionDO> getPermissionListByEnName(List<String> enNameList);

    /**
     * 获取原子权限权限串
     *
     * @param permissionList 原子权限列表
     * @return list
     */
    List<String> getPermissionStringList(List<PermissionDO> permissionList);

    /**
     * 获取站点名称
     *
     * @param siteId 站点id
     * @return 用户站点名称
     */
    String getSiteName(String siteId);

    /**
     * 当前用户是总公司还是分公司人员,1:总公司人员,2:分公司人员,3:其他人员
     *
     * @param tokenUser 当前用户
     * @return 是总公司还是分公司人员, 1:总公司人员,2:分公司人员,3:其他人员
     */
    Integer userIsSuperme(TokenUser tokenUser);

    /**
     * 获取当前登录用户信息
     *
     * @param tokenUser 当前用户
     * @return 当前登录用户信息
     */
    HrUserVO getCurrentUserInfo(TokenUser tokenUser);

    /**
     * 当前用户有权限的分公司
     *
     * @param tokenUser 当前用户
     * @return 有权限的分公司id
     */
    List<String> listChildCompanyId(TokenUser tokenUser);


    /**
     * 小程序,获取当前登录用户信息
     *
     * @param tokenUser 当前用户
     * @return 有权限的分公司id
     */
    HrUserVO smallProgramGetCurrentUserInfo(TokenUser tokenUser);


    /**
     * 查询站点下所有有角色的用户Id
     *
     * @param tokenUser 登录用户
     * @return 站点下所有管理员
     */
    List<String> selectHadRoleUserIdBySiteId(TokenUser tokenUser);

    /**
     * 获取用户所有租户角色成员列表
     *
     * @param userId 用户id
     * @return 成员对象列表
     */
    List<RoleMemberDO> selectAllRoleMemberByUserId(String userId);

    /**
     * 查询用户人力角色(hr+system)
     *
     * @param userId 用户Id
     * @return 人力角色
     */
    List<RoleMemberDO> selectHrRoleMemberByUserId(String userId);

    /**
     * 查询站点下用户人力角色(hr+system)
     *
     * @param userId 用户Id
     * @param siteId 站点Id
     * @return 人力角色
     */
    List<RoleMemberDO> selectHrRoleMemberByUserIdAndSiteId(String userId, String siteId);

    /**
     * 根据权限串获取有权限的原子权限列表
     *
     * @param rightValue 授权串
     * @return 原子权限列表
     */
    List<PermissionDO> getHasRightPermissionListByRightValue(String rightValue);

    /**
     * 根据权限串获取有权限的原子权限列表
     *
     * @param id 原子权限id
     * @return 原子权限列表
     */
    PermissionDO selectDOById(Long id);

    /**
     * 查询组织树
     *
     * @param groupQuery 查询条件
     * @param tokenUser  当前用户
     * @return 原子权限列表
     */
    List<GroupListVO> selectGroupTree(GroupQuery groupQuery, TokenUser tokenUser);

    /**
     * 根据Id查询组织
     *
     * @param groupId   分组Id
     * @param tokenUser 当前用户
     * @return 组织
     */
    GroupDO selectGroupById(String groupId, TokenUser tokenUser);

    /**
     * 根据父级组织Id查找他下面的所有子组织Id
     *
     * @param parentIdList 父级部门Id
     * @param siteId       站点
     * @return 部门Id
     */
    List<String> selectGroupByIdByParent(List<String> parentIdList, String siteId);

    /**
     * 根据父级组织Id查询直属分组
     *
     * @param parentId  父级Id
     * @param tokenUser 当前用户
     * @return 分组
     */
    List<GroupDO> selectGroupByParentId(String parentId, TokenUser tokenUser);

    /**
     * 新增分组
     *
     * @param groupAddDTO 新增参数
     * @param tokenUser   当前用户
     * @return 新增结果
     */
    GroupVO saveGroup(GroupAddDTO groupAddDTO, TokenUser tokenUser);

    /**
     * 批量保存组织成员
     *
     * @param bachSaveList 保存参数
     * @param tokenUser    当前用户
     */
    void bachSaveGroupUser(List<GroupUserDO> bachSaveList, TokenUser tokenUser);

    /**
     * 编辑分组
     *
     * @param groupUpdateDTO 编辑参数
     * @param tokenUser      当前用户
     */
    void updateGroup(GroupUpdateDTO groupUpdateDTO, TokenUser tokenUser);

    /**
     * 删除对应分组下的成员
     *
     * @param groupId 分组Id
     */
    void deleteUserFromGroupId(String groupId);

    /**
     * 根据Id列表查询分组
     *
     * @param groupIdList 分组Id列表
     * @param siteId      站点
     * @return 分组
     */
    List<GroupListVO> findGroupsByIds(List<String> groupIdList, String siteId);

    /**
     * 根据Id查询分组用户
     *
     * @param groupId 分组Id
     * @return 分组
     */
    List<GroupUserDO> selectUserByGroupId(String groupId);

    /**
     * 删除分组
     *
     * @param groupId   分组Id
     * @param tokenUser 当前用户
     */
    void deleteGroup(String groupId, TokenUser tokenUser);

    /**
     * 查询当前登录用户所在分组
     *
     * @param groupType 分组类型
     * @param tokenUser 当前用户
     * @return 所在分组
     */
    List<GroupUserDO> selectGroupCurrentUser(String groupType, TokenUser tokenUser);

    /**
     * 过滤分组Id
     *
     * @param groupIdList 分组Id
     * @param siteId      站点
     */
    void filterGroupId(List<String> groupIdList, String siteId);

    /**
     * 查询父级
     *
     * @param groupIdList 分组Id
     * @param groupType   分组类型
     * @param tokenUser   当前用户
     * @return 父级
     */
    List<BuildParentGroupListVO> buildParentGroupList(List<String> groupIdList, String groupType, TokenUser tokenUser);

    /**
     * 添加租户级别分组下的人员
     *
     * @param groupType 分组类型
     * @param siteId    站点
     * @return userIdList
     */
    List<String> selectSiteGroupUser(String groupType, String siteId);

    /**
     * 查询租户级别分组
     *
     * @param groupType 分组类型
     * @param siteId    站点
     * @return 分组
     */
    GroupListVO selectSiteGroup(String groupType, String siteId);
    /**
     * 判断手机号是否是管理员（租户的一般管理员或者超级管理员）
     * @param phone
     * @param tokenUser
     * @return
     */
    boolean isHrAdmin(String phone, TokenUser tokenUser);

}
